/* 
 * @(#)RecoleccionBean.java 
 *  
 * Clase para la gestion de recolecciones.  
 * 
 * @version 1.0
 * @date 01/11/12 
 * @author Ricardo Escobar 
 *  
 */
package muhnes.sizoo.controlador;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.model.SelectItem;
import muhnes.sizoo.dal.FabricaDAO;
import muhnes.sizoo.dal.InternacionalDao;
import muhnes.sizoo.dal.NacionalDao;
import muhnes.sizoo.dal.RecoleccionDao;
import muhnes.sizoo.dal.RecolectorDao;
import muhnes.sizoo.dal.RecolectorDaoImpl;
import muhnes.sizoo.dal.ZonaDao;
import muhnes.sizoo.modelo.Internacional;
import muhnes.sizoo.modelo.Nacional;
import muhnes.sizoo.modelo.Recoleccion;
import muhnes.sizoo.modelo.Recolector;
import muhnes.sizoo.modelo.Zona;
import muhnes.sizoo.util.TipoRecoleccion;
import muhnes.sizoo.util.Transaccion;
import org.primefaces.event.FlowEvent;

/**
 * Clase que contiene los metodos que controlan la vista de recolecciones
 * @author Ricardo Orellana
 */
@ManagedBean(name = "recoleccionBean")
@ViewScoped
public class RecoleccionBean extends CRUDBean< Recoleccion, RecoleccionDao > 
    implements Serializable {

    private TipoRecoleccion tipoRecoleccion;
    private Nacional nacional;
    private Recolector recolector;
    private Internacional internacional;
    private List< SelectItem > itemsRecolectores;
    private List< SelectItem > itemsZonas;
    private List< SelectItem > itemsEstado;
    
    /**
     * Constructor de la clase
     */
    public RecoleccionBean() {
        super( Recoleccion.class );
        vistaProtegida = "recoleccion";
        tipoRecoleccion = TipoRecoleccion.INDEFINIDO;
        nacional = new Nacional();
        recolector = new Recolector();
        internacional = new Internacional();
    }
    
    /**
     * Getter de tipoRecoleccion
     *  
     */
    public TipoRecoleccion getTipoRecoleccion() {
        return tipoRecoleccion;
    }
    
    /**
     * Setter de tipoRecoleccion
     * @param tipoRecoleccion 
     */
    public void setTipoRecoleccion(TipoRecoleccion tipoRecoleccion) {
        this.tipoRecoleccion = tipoRecoleccion;
    }
    
    /**
     * Getter de nacional
     *  
     */
    public Nacional getNacional() {
        return nacional;
    }

    /**
     * Setter de nacional
     * @param nacional 
     */
    public void setNacional(Nacional nacional) {
        this.nacional = nacional;
    }

    /**
     * Getter de recolector
     *  
     */
    public Recolector getRecolector() {
        return recolector;
    }

    /**
     * Setter de recolector
     * @param recolector 
     */
    public void setRecolector(Recolector recolector) {
        this.recolector = recolector;
    }

    /**
     * Getter de internacional
     *  
     */
    public Internacional getInternacional() {
        return internacional;
    }

    /**
     * Setter de internacional
     * @param internacional 
     */
    public void setInternacional(Internacional internacional) {
        this.internacional = internacional;
    }
    
    /**
     * Metodo que devuelve una lista de estados
     * @return objeto list
     */
    public List<SelectItem> getItemsEstado() {
        if(itemsEstado == null){
            itemsEstado = new ArrayList< SelectItem >();
            SelectItem habilitado = new SelectItem("Habilitado");
            itemsEstado.add(habilitado);
            SelectItem deshabilitado = new SelectItem("Deshabilitado");
            itemsEstado.add(deshabilitado);
        }
        return itemsEstado;
    }
    
    /**
     * Metodo que prepara la adicion de un dato
     * @param event 
     */
    @Override
    public void prepararAdicion( ActionEvent event  ){
        entidad = new Recoleccion();
        nacional = new Nacional();
        internacional = new Internacional();
    }
    
    /**
     * Metodo que prepara la modificacion de una dato
     * @param recoleccion 
     */
    @Override
    public void prepararModificacion( Recoleccion recoleccion ){
        if(recoleccion.getTiporecoleccion() == 'N'){
            this.entidad = recoleccion;
            tipoRecoleccion = TipoRecoleccion.NACIONAL;
            operacionActual = Transaccion.ACTUALIZACION;
            nacional = castNacional(recoleccion);
            
        } else if(recoleccion.getTiporecoleccion() == 'I'){
            internacional = (Internacional)recoleccion;
            this.entidad = recoleccion;
            tipoRecoleccion = TipoRecoleccion.INTERNACIONAL;            
            operacionActual = Transaccion.ACTUALIZACION;
        };
        
    }
    
    /**
     * Metodo que actualiza un tipo de recoleccion
     * @param event 
     */
    public void actualizarTipoRecoleccion( AjaxBehaviorEvent event ) {
        if( entidad.getTiporecoleccion() == 'N' ) {
            tipoRecoleccion = TipoRecoleccion.NACIONAL;
        }
        else if( entidad.getTiporecoleccion() == 'I' ) {
            tipoRecoleccion = TipoRecoleccion.INTERNACIONAL;
        }
    }
    
    /**
     * Metodo que comprueba que no ocurrieron errores de validacion
     * @param event
     *  
     */
    public String procesarFlujoAdicion( FlowEvent event ) {  
        return event.getNewStep();  
    } 
    
    /**
     * Metodo que agrega una nueva entidad
     * @param event 
     */
    @Override
    public void agregarEntidad( ActionEvent event ) {
        RecoleccionDao recoleccionDao = FabricaDAO.crearRecoleccionDao();
        
        if( tipoRecoleccion == TipoRecoleccion.NACIONAL &&
            nacional != null ) {
            nacional.setTiporecoleccion(entidad.getTiporecoleccion());
            nacional.setFecharecoleccion(entidad.getFecharecoleccion());
            nacional.setLatitud(entidad.getLatitud());
            nacional.setLongitud(entidad.getLongitud());
            nacional.setObservaciones(entidad.getObservaciones());
            NacionalDao nacionalDao = FabricaDAO.crearNacionalDao();
            nacional.setHabilitado( true );
            nacionalDao.guardar( nacional );
        }
        else if( tipoRecoleccion == TipoRecoleccion.INTERNACIONAL &&
                 internacional != null ) {
            internacional.setTiporecoleccion(entidad.getTiporecoleccion());
            internacional.setFecharecoleccion(entidad.getFecharecoleccion());
            internacional.setLatitud(entidad.getLatitud());
            internacional.setLongitud(entidad.getLongitud());
            internacional.setObservaciones(entidad.getObservaciones());
            InternacionalDao internacionalDao = FabricaDAO.crearInternacionalDao();
            internacional.setHabilitado( true );
            internacionalDao.guardar( internacional );
        }
        else {
            //TODO Throw not defined exception
        }
        
        recrearModelo();
    }
    
    /**
     * Metodo que modifica la informacion de una recoleccion
     * @param event 
     */
    public void modificarRecoleccion( ActionEvent event ){
        
        if(entidad.getTiporecoleccion() == 'N'){
            NacionalDao nacionalDao = FabricaDAO.crearNacionalDao();
            nacionalDao.actualizar(nacional);
        } else if(entidad.getTiporecoleccion() == 'I'){
            InternacionalDao internacionalDao = FabricaDAO.crearInternacionalDao();
            internacionalDao.actualizar(internacional);
        }
        
    }  
    
    /**
     * Metodo que elimina una recoleccion
     * @param event 
     */
    @Override
     public void eliminarEntidad( ActionEvent event ){
        if( !validarDependencia() ) {
            return;
        }
        
        RecoleccionDao recoleccionDao = FabricaDAO.crearRecoleccionDao();
        entidad.setHabilitado(false);
        recoleccionDao.actualizar( entidad);
        recrearModelo();
    }
    
    /**
     * Metodo que devuelve una lista de recolectores
     * @return objeto list
     */
    public List< SelectItem > getItemsRecolectores() {
        if( itemsRecolectores == null ) {
            itemsRecolectores = new ArrayList< SelectItem >();
            RecolectorDao dao = new RecolectorDaoImpl();
            for( Recolector recolector : dao.buscarHabilitados() ) {
                Recolector r = dao.removerProxy(recolector);
                SelectItem item = new SelectItem( r, r.getNombre() );
                itemsRecolectores.add( item );
            }
        }
        return itemsRecolectores;
    }
    
    /**
     * Metodo que devuelve una lista de zonas
     * @return objeto list
     */
    public List< SelectItem > getItemsZonas() {
        if( itemsZonas == null ) {
            itemsZonas = new ArrayList< SelectItem >();
            ZonaDao zonaDao = FabricaDAO.crearZonaDao();
            for( Zona zona : zonaDao.buscarTodos() ) {
                Zona z = zonaDao.removerProxy(zona);
                SelectItem item = new SelectItem( z, z.getUbicacion() );
                itemsZonas.add( item );
            }
        }
        return itemsZonas;
    }
    
    /**
     * Metodo que convierte una recoleccion nacional
     * @param rec
     *  
     */
    public Nacional castNacional(Recoleccion rec) {
        return (Nacional)rec;
    }
    
    /**
     * Metodo que convierte una recoleccion internacional
     * @param rec
     *  
     */
    public Internacional castInternacional(Recoleccion rec) {
        return (Internacional)rec;
    }

    /**
     * Metodo que instancia un nuevo Recolecciondao
     *  
     */
    @Override
    protected RecoleccionDao getDAO () {
        return FabricaDAO.crearRecoleccionDao();
    }

    /**
     * 
     * @param transaccion indica que transaccion se debera realizar 
     * @return objeto de tipo boolean que indica que tipo de transaccion se realizara
     */
    @Override
    protected boolean debeValidar (Transaccion transaccion) {
        boolean validacion = false;
        
        switch( transaccion ) {
            case INSERCION:
            case ELIMINACION:
                validacion = true;
        }
        
        return validacion;
    }
    
}
